import 'package:common/constant/constant.dart';
import 'package:flutter/material.dart';
import 'package:resource/generated/l10n.dart';

import '../network/business_response.dart';
import '../network/code_msg_model.dart';
import 'base_lv_adapter.dart';
import 'base_state.dart';

///
///网格布局基类
///<D> 网络请求返回data里的数据类型
///<T> 列表List中存放的数据类型

abstract class BaseGvState<W extends StatefulWidget, T> extends BaseState<W>
    implements BusinessResponse {

  bool isRefresh = false;

  bool isLoadMore = false;

  bool _hasMoreData = false;

  bool _enableRefresh = true;

  bool _enableLoadMore = true;

  //当前页数
  @protected
  int page = 1;

  late final BaseLvAdapter<T> adapter;

  final ScrollController _scrollController = ScrollController();

  @override
  void onStateInit() {
    adapter = onInitAdapter();
    _scrollController.addListener(() {
      if ((_scrollController.position.pixels == _scrollController.position.maxScrollExtent) &&
          onEnableLoadMore() &&
          _hasMoreData) {
        onPullLoadMore();
      }
    });
  }

  @override
  Widget onBodyCreate() {
    return Column(
      children: <Widget>[
        onTopViewCreate(),
        Expanded(child: _createGridView()),
        _buildLoadMoreIndicator(),
        onBottomViewCreate(),
      ],
    );
  }

  @override
  void onFail(CodeMsgModel baseResponseModel) {
    super.onFail(baseResponseModel);
    refreshOrLoadFailed();
  }

  RefreshIndicator _buildRefreshIndicator() {
    return RefreshIndicator(
      onRefresh: onPullRefresh,
      child: _buildGridView(),
    );
  }

  GridView _buildGridView() {
    return GridView.builder(
      controller: _scrollController,
      gridDelegate: onGridDelegate(),
      physics: const AlwaysScrollableScrollPhysics(),
      itemCount: (adapter.isEmpty()) ? 0 : (adapter.getItemCount()),
      itemBuilder: (BuildContext context, int index) {
        return _onItemCreateAndDataBind(adapter.getItem(index) as T, index);
      },
    );
  }

  @protected
  SliverGridDelegate onGridDelegate(){
    ///该子类实现了一个横轴子元素为固定最大长度的layout算法
    return SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: onItemMaxWidth());
  }

  ///元素在横轴上的最大长度
  @protected
  double onItemMaxWidth(){
    return 30;
  }

  Widget _buildLoadMoreIndicator() {
    if (onEnableLoadMore()) {
      if (_hasMoreData) {
        //还有更多数据可以加载
        return const Padding(
          padding: EdgeInsets.all(10.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              RefreshProgressIndicator(color: Colors.blue),
            ],
          ),
        );
      } else {
        //当没有更多数据可以加载的时候，
        return Center(child: Text(S.current.no_more_data, style: const TextStyle(color: Colors.black12)));
      }
    } else {
      return Container();
    }
  }

  /// 是否允许下拉
  bool onEnableRefresh() {
    return _enableRefresh;
  }

  /// 是否允许上拉
  bool onEnableLoadMore() {
    return _enableLoadMore;
  }

  ///创建视图时调用
  Widget? _onItemCreateAndDataBind(T t, int index){
    return adapter.onItemCreateAndDataBind(t, index);
  }

  //创建视图时调用
  @protected
  Widget onTopViewCreate() {
    return Container();
  }

  //创建视图时调用
  Widget _createGridView() {
    if (onEnableRefresh()) {
      return _buildRefreshIndicator();
    } else {
      return _buildGridView();
    }
  }

  ///创建视图时调用
  @protected
  Widget onBottomViewCreate() {
    return Container();
  }

  BaseLvAdapter<T> onInitAdapter();

  /// 下拉刷新的通用回调
  /// 需要特殊处理时，重写该方法
  @protected
  Future<void> onPullRefresh() async {
    page = 1;
    isRefresh = true;
  }

  /// 上拉加载的通用回调
  /// 需要特殊处理时，重写该方法
  Future<void> onPullLoadMore() async {
    page++;
    isLoadMore = true;
  }

  void refreshOrLoadSuccess(List<T> list, {int total = Constant.zero}) {
    if (isRefresh) {
      adapter.setData(list);
    } else if (isLoadMore) {
      adapter.appendDataAndNotify(list);
    } else {
      adapter.setData(list);
    }
    _hasMoreData = total > adapter.getItemCount();
    isLoadMore = false;
    isRefresh = false;
    if(mounted){
      setState(() {});
    }

  }

  void refreshOrLoadFailed() {
    if (isRefresh) {
      adapter.clearDataAndNotify();
    } else if (isLoadMore) {
      page--;
    } else {
      adapter.clearDataAndNotify();
    }
    isLoadMore = false;
    isRefresh = false;
  }

  void setEnableRefresh(bool enableRefresh){
    _enableRefresh = enableRefresh;
  }

  void setEnableLoadMore(bool enableLoadMore){
    _enableLoadMore = enableLoadMore;
  }

  @override
  void onDestroy() {
    super.onDestroy();
    _scrollController.dispose();
  }
}
